﻿using System;
using System.IO;
using Moonlite.Compiling;
using Moonlite.Platform.General;
using Moonlite.ExtensionApi;
using Moonlite.ExtensionApi.GlobalInterfaces;

namespace Moonlite.CommandPrompt {
    class Program {
        private static ArgumentParser ArgumentParser { get; set; }
        static void Main(string[] args) {
            WriteSignature();
            if (args.Length > 0) {
                if (args[0] == "compile" && (args.Length == 2 || args.Length == 3)) ProcessCompileCommand();
                if (args[0] == "start" && args.Length == 2) ProcessStartCommand();
                if (args[0] == "compilestart" && args.Length == 2) ProcessCompileStartCommand();
                if (args[0] == "resetdm" && (args.Length == 1 || args.Length == 2)) ProcessResetDmCommand();
            }

            while (true) {
                string input = Console.ReadLine();
                if (input == "exit") break;
                ArgumentParser = new ArgumentParser(input);
                if ((ArgumentParser[0] == "/?" || ArgumentParser[0] == "/help") && (ArgumentParser.Count == 1)) ProcessHelpCommand();
                if (ArgumentParser[0] == "compile" && (ArgumentParser.Count == 2 || ArgumentParser.Count == 3)) ProcessCompileCommand();
                if (ArgumentParser[0] == "start" && ArgumentParser.Count == 2) ProcessStartCommand();
                if (ArgumentParser[0] == "compilestart" && ArgumentParser.Count == 2) ProcessCompileStartCommand();
                if (ArgumentParser[0] == "resetdm" && (ArgumentParser.Count == 1 || ArgumentParser.Count == 2)) ProcessResetDmCommand();
            }
        }

        static void ProcessHelpCommand() {
            WriteSignature();
            Console.WriteLine("Available commands:");
            Console.WriteLine("/? or /help");
            Console.WriteLine("    Displays the list of available commands along with their descriptions.");
            Console.WriteLine("    Takes no arguments.");
            Console.WriteLine();
            Console.WriteLine("exit");
            Console.WriteLine("    Exits the console application.");
            Console.WriteLine("    Takes no arguments.");
            Console.WriteLine();
            Console.WriteLine("compile");
            Console.WriteLine("    Compiles the given project. Can optionally show compilation GUI, if available.");
            Console.WriteLine("    (path) [-showgui]");
            Console.WriteLine("    Example: compile \"C:\\ExampleProject\\ExampleProject.jxproj\" -showgui");
            Console.WriteLine();
            Console.WriteLine("start");
            Console.WriteLine("    Runs the given project in the associated game.");
            Console.WriteLine("    (path)");
            Console.WriteLine("    Example: start \"C:\\ExampleProject\\ExampleProject.jxproj\"");
            Console.WriteLine();
            Console.WriteLine("compilestart");
            Console.WriteLine("    Compiles and starts the given project in the associated game.");
            Console.WriteLine("    (path) [-showgui]");
            Console.WriteLine("    Example: compilestart \"C:\\ExampleProject\\ExampleProject.jxproj\"");
            Console.WriteLine();
            Console.WriteLine("resetdm");
            Console.WriteLine("    Resets the dock layout GUI to the defaults. Optionally resets all settings.");
            Console.WriteLine("    [-resetall]");
            Console.WriteLine("    Example: resetdm -resetall");
            Console.WriteLine();
        }

        static void ProcessCompileCommand() {
            ProcessCompileCommand(false);
        }

        static void ProcessCompileCommand(bool shouldShowGui) {
            bool showGui = ArgumentParser.Exists("-showgui") || shouldShowGui;
            string path = ArgumentParser[1];
            if (!File.Exists(path)) {
                Console.WriteLine("Error compiling project: file at given path doesn't exist.");
                return;
            }

            if (!(Path.GetExtension(path) == "." + Global.JassProjectExtension || Path.GetExtension(path) == "." + Global.GalaxyProjectExtension)) {
                Console.WriteLine("Error compiling project: file at given path isn't a valid Moonlite Map Studio project file.");
                return;
            }

            IProject project = Global.Instance.OpenProject(path, false);
            if (project == null || string.IsNullOrEmpty(project.Name) || string.IsNullOrEmpty(project.Path)) {
                Console.WriteLine("Error compiling project: project could not be loaded.");
                return;
            }

            if (project.GetAllFiles().Count == 0) {
                Console.WriteLine("Error compiling project: project does not contain any files.");
                return;
            }

            CompilerManager.LoadCompilers();
            if (project.Type == ProjectType.Jass) {
                if (showGui) CompilerManager.ExecuteWc3(project);
                else CompilerManager.ExecuteCLIJassHelper(project);
            }
            else if (project.Type == ProjectType.Galaxy) {
                CompilerManager.ExecuteAndromeda(project, !showGui, !showGui, true, false, "");
            }

            Console.WriteLine("Compilation was succesful.");
        }

        static void ProcessStartCommand() {
            string path = ArgumentParser[1];
            if (!File.Exists(path)) {
                Console.WriteLine("Error compiling project: file at given path doesn't exist.");
                return;
            }

            if (!(Path.GetExtension(path) == "." + Global.JassProjectExtension || Path.GetExtension(path) == "." + Global.GalaxyProjectExtension)) {
                Console.WriteLine("Error compiling project: file at given path isn't a valid Moonlite Map Studio project file.");
                return;
            }

            IProject project = Global.Instance.OpenProject(path, false);
            if (project == null || string.IsNullOrEmpty(project.Name) || string.IsNullOrEmpty(project.Path)) {
                Console.WriteLine("Error compiling project: project could not be loaded.");
                return;
            }

            if (project.GetAllFiles().Count == 0) {
                Console.WriteLine("Error compiling project: project does not contain any files.");
                return;
            }

            GameManager.Instance.StartGame(project, false);
            Console.WriteLine("Starting game was succesful.");
        }

        static void ProcessCompileStartCommand() {
            ProcessCompileCommand(true);
            ProcessStartCommand();
        }
        
        static void ProcessResetDmCommand() {
            bool resetAll = ArgumentParser.Exists("-resetall");
            string settingsPath = Global.GetAppDataSettingsFolder();
            if (!Directory.Exists(settingsPath)) {
                return;
            }

            bool success = true;
            try {
                if (resetAll) {
                    DirectoryHelper.DeleteDirectory(settingsPath);
                    DirectoryHelper.CreateFolderPath(settingsPath);
                }
                else {
                    File.Delete(settingsPath + "\\" + Global.DockLayoutFileName);
                }
            }
            catch (Exception exception) {
                Console.WriteLine("Error resetting settings: " + exception.Message);
                success = false;
            }

            if (success) Console.WriteLine("Reset was succesful.");
        }

        static void WriteSignature() {
            Console.WriteLine("Copyright (C) Vestras Productions 2009");
            Console.WriteLine("All right reserved");
            Console.WriteLine();
        }
    }
}
